﻿using IPC.DbMapper;
using IPC.ListConnect.EquipBuild;
using IPC.LogCommon.log4net;
using IPC.MongoDB;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace IPC.ListConnect.Profinet
{
    public class Equip: BaseClass
    {
        private bool _isRunning = false;

        private string _ip = string.Empty;
        private string _port = string.Empty;
        private string _name = string.Empty;
        private string slot = string.Empty;
        private string _rack = string.Empty;
        private string _type = string.Empty;
        private string _channelType = string.Empty;
        private string _equipFullName = string.Empty;
        private string _channelName = string.Empty;
        private List<Tag> _readTags = new List<Tag>();
        private System.Timers.Timer _timer;
        private Build build;

        /// <summary>
        /// 设备ip
        /// </summary>
        public string Ip { get => _ip;
            set
            {
                if (_ip != value && _isRunning)
                {
                    RestartRead();
                }
                _ip = value;
            }
        }
        /// <summary>
        /// 设备端口
        /// </summary>
        public string Port { get => _port; set
            {
                if (_port != value && _isRunning)
                {
                    RestartRead();
                }
                _port = value;
            }
        }
        /// <summary>
        /// 设备名称
        /// </summary>
        public string Name { get => _name; set => _name = value; }
        /// <summary>
        /// 设备槽口号
        /// </summary>
        public string Slot { get => slot;
            set
            {
                if (slot != value && _isRunning)
                {
                    RestartRead();
                }
                slot = value;
            }
        }
        /// <summary>
        /// 设备机架号
        /// </summary>
        public string Rack { get => _rack; set
            {
                if (_rack != value && _isRunning)
                {
                    RestartRead();
                }
                _rack = value;
            }
        }
        /// <summary>
        /// 设备类型
        /// </summary>
        public string Type { get => _type; set
            {
                if (_type != value && _isRunning)
                {
                    RestartRead();
                }
                _type = value;
            }
        }
        /// <summary>
        /// 组
        /// </summary>
        public Dictionary<string,Group> Groups { get; set; } = new Dictionary<string, Group>();
        /// <summary>
        /// 通道类型
        /// </summary>
        public string ChannelType { get => _channelType; set => _channelType = value; }
        /// <summary>
        /// 标签
        /// </summary>
        public Dictionary<string, Tag> Tags { get; set; } = new Dictionary<string, Tag>();
        /// <summary>
        /// 设备全名
        /// </summary>
        public string EquipFullName { get => _equipFullName; set => _equipFullName = value; }
        /// <summary>
        /// 通道名
        /// </summary>
        public string ChannelName { get => _channelName; set => _channelName = value; }

        public Equip():base(){
            
        }

        public Equip(string guid,string ip,string port,string slot,string rack,string type,string channelType,string channelName,string name,string equipFullName) : base()
        {
            Guid = guid;
            Ip = ip;
            Port = port;
            Slot = slot;
            Rack = rack;
            Type = type;
            ChannelType = channelType;
            ChannelName = channelName;
            Name = name;
            EquipFullName = equipFullName;

            StartRead();
        }

        #region 启动定时器读取
        public void StartRead()
        {
            if (!_isRunning)
            {
                LogClass.Instance.Info($"启动设备读取器{ChannelType},ip{Ip},port{Port}");
                build = new Build(ChannelType, Type, Ip, Port.ToInt(0), Slot.ToByte(0), Rack.ToByte(0));
                _isRunning = true;

                if (_timer != null)
                {
                    _timer.Stop();
                    _timer.Dispose();
                    _timer = null;
                }

                _timer = new System.Timers.Timer();
                _timer.Elapsed += _timer_Elapsed;
                _timer.Interval = 10;
                _timer.Start();
            }
        }

        private void _timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            if (_timer != null)
            {
                _timer.Enabled = false;
            }
            
            _readTags.Clear();
            foreach (var group in Groups.Values.ToArray())
            {
                foreach (var tag in group.Tags.Values.ToArray())
                {
                    _readTags.Add(tag);
                }
            }
            foreach (var item in Tags.Values.ToArray())
            {
                _readTags.Add(item);
            }

            Dictionary<string, Tag> tagValues = build.Read(_readTags, out string connectResult);
            LogClass.Instance.Info($"设备读取结果{JsonConvert.SerializeObject(tagValues)}");
            foreach (var item in tagValues)
            {
                string fullName = item.Key;
                Tag tagValue = item.Value;
                string[] names = fullName.Split('.');
                if (names.Count() == 3)
                {
                    Tags[fullName].RealValue = tagValue.Value;
                    Tags[fullName].IsSuccess = tagValue.IsSuccess;
                    Tags[fullName].Result = tagValue.Result;
                    MongoOperateReal.Instance.Insert(fullName, DateTime.Now.ToString(), tagValue.Value.ToDouble(-99));
                }
                else if (names.Count() == 4)
                {
                    Groups[$"{names[0]}.{names[1]}.{names[2]}"].Tags[fullName].RealValue = tagValue.Value;
                    Groups[$"{names[0]}.{names[1]}.{names[2]}"].Tags[fullName].IsSuccess = tagValue.IsSuccess;
                    Groups[$"{names[0]}.{names[1]}.{names[2]}"].Tags[fullName].Result = tagValue.Result;
                    MongoOperateReal.Instance.Insert(fullName, DateTime.Now.ToString(), tagValue.Value.ToDouble(-99));
                }
            }
            if (_timer != null)
                _timer.Enabled = true;
        } 
        #endregion

        private void RestartRead()
        {
            if(_isRunning)
            {
                _isRunning = false;
                StartRead();
            }
        }
        
        public void WillClose()
        {
            if (_timer != null)
            {
                foreach (var itemTag in Tags.Values)
                {
                    itemTag.WillClose();
                }
                foreach (var itemGroups in Groups.Values)
                {
                    foreach (var itemTag in itemGroups.Tags.Values)
                    {
                        itemTag.WillClose();
                    }
                }
                _timer.Stop();
                _timer.Dispose();
                _timer = null;
            }
        }
    }
}
